package com.cloud.bssp.java8.stream;

import java.util.function.Function;
import java.util.stream.LongStream;
import java.util.stream.Stream;

/**
 * @description： 测试并行的性能
 * @author：weirx
 * @date：2021/10/22 15:20
 * @version：3.0
 */
public class TestStreamParallel {

    /**
     * description: 传入一个函数和一个数值，此方法会对传入的方法执行10次，取出最短执行时间
     *
     * @param adder
     * @param n
     * @return: long
     * @author: weirx
     * @time: 2021/10/22 15:29
     */
    public static long measureSumPerf(Function<Long, Long> adder, long n) {
        long fastest = Long.MAX_VALUE;
        for (int i = 0; i < 10; i++) {
            long start = System.nanoTime();
            adder.apply(n);
            long duration = (System.nanoTime() - start) / 1_000_000;
            if (duration < fastest) {
                fastest = duration;
            }
        }
        return fastest;
    }

    /**
     * description: 对输入数值求和
     *
     * @param aLong
     * @return: java.lang.Long
     * @author: weirx
     * @time: 2021/10/25 10:02
     */
    private static Long testFor(Long aLong) {
//        jdk1.7求和
        long result = 0;
        for (long i = 1L; i <= aLong; i++) {
            result += i;
        }
        return result;
    }

    /**
     * description: 对输入数值求和
     *
     * @param aLong
     * @return: java.lang.Long
     * @author: weirx
     * @time: 2021/10/25 10:02
     */
    private static Long testStreamParallel(Long aLong) {

//        jdk1.8求和 - 并行
        return Stream.iterate(0L, i -> i + 1).limit(aLong).parallel().reduce(0L, Long::sum);
    }

    /**
     * description: 对输入数值求和
     *
     * @param aLong
     * @return: java.lang.Long
     * @author: weirx
     * @time: 2021/10/25 10:02
     */
    private static Long testStream(Long aLong) {

//        jdk1.8求和 - 非并行
        return Stream.iterate(0L, i -> i + 1).limit(aLong).reduce(0L, Long::sum);
    }

    /**
     * description: 使用LongStream.rangeClosed求和
     * @param aLong
     * @return: java.lang.Long
     * @author: weirx
     * @time: 2021/10/25 10:53
     */
    private static Long testRangeClosed(Long aLong) {
        return LongStream.rangeClosed(0, aLong).reduce(0L, Long::sum);
    }

    /**
     * description: 使用LongStream.rangeClosed求和
     * @param aLong
     * @return: java.lang.Long
     * @author: weirx
     * @time: 2021/10/25 10:53
     */
    private static Long testRangeClosedParallel(Long aLong) {
        return LongStream.rangeClosed(0, aLong).parallel().reduce(0L, Long::sum);
    }

    public static void main(String[] args) {
        System.out.println("最短耗时：" + measureSumPerf(TestStreamParallel::testRangeClosedParallel, 10000000) + "ms");
    }
}
